﻿using SqlSugar;
using System.Linq.Expressions;
using System.Reflection;

namespace Zy.Shared.Repository.ClickHouse.Repositorys
{
    /// <summary>
    /// SqlSugar库
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class SqlSugarRespository<TEntity>:ISqlSugarRespository<TEntity> where TEntity : SqlSugarEntity, new()
    {
        private ISqlSugarClient _client;
        public SqlSugarRespository(ISqlSugarClient client)
        {
            _client = client;
        }
        public async Task<int> InsertAsync(TEntity entity)
        {
            if(!TableIsExist())
                CreateTable();
            return await _client.Insertable(entity).ExecuteCommandAsync();
        }
        public async Task<int> InsertAsync(List<TEntity> entities)
        {
            if (!TableIsExist())
                CreateTable();
            return await _client.Insertable(entities).ExecuteCommandAsync();
        }
        public IInsertable<TEntity> Insertable(List<TEntity> entities)
        {
            if (!TableIsExist())
                CreateTable();
            return _client.Insertable(entities);
        }
        public IInsertable<TEntity> Insertable(TEntity entity)
        {
            if (!TableIsExist())
                CreateTable();
            return _client.Insertable(entity);
        }
        public async Task<int> UpdateAsync(TEntity entity)
        {
            return await _client.Updateable(entity).ExecuteCommandAsync();
        }
        public async Task<int> UpdateAsync(List<TEntity> entities)
        {
            return await _client.Updateable(entities).ExecuteCommandAsync();
        }
        public async Task<int> UpdateAsync(Expression<Func<TEntity, TEntity>> columns,Expression<Func<TEntity, bool>> expression)
        {
            return await _client.Updateable<TEntity>().Where(expression).SetColumns(columns).ExecuteCommandAsync();
        }
        public async Task<int> UpdateAsync(List<TEntity> entity, Expression<Func<TEntity, object>> updateColumns)
        {
            return await _client.Updateable(entity).UpdateColumns(updateColumns).ExecuteCommandAsync();
        }
        public IUpdateable<TEntity> Updateable(TEntity entity)
        {
            return _client.Updateable(entity);
        }
        public IUpdateable<TEntity> Updateable(List<TEntity> entity, Expression<Func<TEntity, object>> updateColumns, Expression<Func<TEntity, bool>> expression)
        {
            return _client.Updateable(entity).UpdateColumns(updateColumns).Where(expression);
        }
        public IUpdateable<TEntity> Updateable(List<TEntity> entity, Expression<Func<TEntity, bool>> expression)
        {
            return _client.Updateable(entity).Where(expression);
        }
        public IUpdateable<TEntity> Updateable(List<TEntity> entity, Expression<Func<TEntity, object>> updateColumns)
        {
            return  _client.Updateable(entity).UpdateColumns(updateColumns);
        }
        public async Task<int> DeleteAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _client.Deleteable(expression).ExecuteCommandAsync();
        }
        public IDeleteable<TEntity> Deleteable(Expression<Func<TEntity, bool>> expression)
        {
            return  _client.Deleteable(expression);
        }
        public ISugarQueryable<TEntity> SqlQueryable(string sql)
        {
            return _client.SqlQueryable<TEntity>(sql);
        }
        public ISugarQueryable<TEntity> Queryable()
        {
            return _client.Queryable<TEntity>();
        }
        public ISugarQueryable<TEntity> Queryable(Expression<Func<TEntity, bool>> expression)
        {
            return _client.Queryable<TEntity>().Where(expression);
        }
        public ISugarQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression)
        {
            return _client.Queryable<TEntity>().Where(expression);
        }
        public async Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _client.Queryable<TEntity>().Where(expression).ToListAsync();
        }
        public async Task<List<TEntity>> SqlQueryAsync(string sql)
        {
            return await _client.SqlQueryable<TEntity>(sql).ToListAsync();
        }

        public async Task<int> CountAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _client.Queryable<TEntity>().Where(expression).CountAsync();
        }
        public async Task<TResult> FetchAsync<TResult>(Expression<Func<TEntity, TResult>> selector, Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression = null)
        {
            return await _client.Queryable<TEntity>().Where(whereExpression).OrderBy(orderByExpression).Select(selector).FirstAsync();
        }

        /// <summary>
        /// 查看表是否存在
        /// </summary>
        /// <returns></returns>
        private bool TableIsExist()
        {
            var tableName = (typeof(TEntity).GetCustomAttributes<SugarTable>(true).FirstOrDefault()?.TableName) ?? throw new Exception("This class is not Sqlsugar Table.");
            //怎么获取sqlsugar实体类中的表名
            //((SugarTable<T>)).TableName;
            return _client.DbMaintenance.IsAnyTable(tableName);
        }
        /// <summary>
        /// 创建表
        /// </summary>
        private void CreateTable()
        {
            //_client.DbMaintenance.CreateDatabase(); //创建数据库
            _client.CodeFirst.InitTables(typeof(TEntity));
        }

    }
}
